#ifndef _B_PLUS_NODE_LEAF__HPP
#define _B_PLUS_NODE_LEAF__HPP 1
#include <Pair.hpp>
#include <Types.h>
#include <stdio.h>
namespace MAIL{

	/**
	  @struct BPlusNodeType BPlusTree.hpp <BPlusTree.hpp>
	  @brief Type of B+Tree node.
	*/
	struct BPlusNodeType{
		INT_64 id;
		/** Type of node; type of node cannot be changed */
		const bool                   is_leaf;
		/** Parent node. Parent node ID                  */
		INT_64 		             parent;


		/**
		  @brief Constructor
		  @param bIsLeaf - is node leaf or no
		  @param pParent - Parent node ID
		*/
		inline BPlusNodeType(bool bIsLeaf, INT_64  pParent): is_leaf(bIsLeaf) { 
			//default id value for node
			id = 0;
			parent = pParent;
		 }
	};

	/**
	  @struct BPlusNode BPlusTree.hpp <BPlusTree.hpp>
	  @brief Node of B+Tree.
	*/
	template <typename T, INT_64 TreeWidth>
	struct BPlusNode : public BPlusNodeType{
		/** Node size            */
		INT_64                      size;
		/** Array of keys        */
		T                           keys[TreeWidth + 1];
		/** Array of child nodes */
		INT_64                      children[TreeWidth + 2];

		/**
		  @brief Constructor
		  @param pParent - parent node
		  @param bIsLeaf - is leaf or not
		*/
		inline BPlusNode(INT_64 pParent = 0): BPlusNodeType(false, pParent), size(0) { ;; }
	};

	/**
	  @struct BPlusLeaf BPlusTree.hpp <BPlusTree.hpp>
	  @brief Leaf of B+Tree.
	*/
	template <typename T, typename V, INT_64 TreeWidth>
	struct BPlusLeaf : public BPlusNodeType{
		/** Node size            */
		INT_64                       size;
		/** Array of pairs       */
		Pair<T, V>                   pairs[TreeWidth + 1];
		/** Next leaf node       */
		INT_64                      next;

		/**
		  @brief Constructor
		  @param pParent - parent node
		  @param bIsLeaf - is leaf or not
		*/
		inline BPlusLeaf(INT_64 pParent = 0): BPlusNodeType(true, pParent), size(0), next(0) {}
		
		/**
		* @brief get size of all struct with data
		*/
		inline static INT_32 getSizeOf() {
			return sizeof(BPlusLeaf) + (TreeWidth + 1) * V::getSizeData();
		}

		/**
		* @brief operator ==
		* @param oLeaf - leaf to compare
		*/
		bool operator == (const BPlusLeaf &oLeaf){
			bool flag = true;
			// check all pairs
			for (INT_32 iI = 0; iI < size; iI++){
				if (pairs[iI].key != oLeaf.pairs[iI].key){
					flag = false;
					break;
				}
				if (this->pairs[iI].value !=  oLeaf.pairs[iI].value){
					flag = false;
					break;
				}
			}
			return flag && 
			       size == oLeaf.size &&
			       id == oLeaf.id &&
			       parent == oLeaf.parent &&
			       next == oLeaf.next;
		}
	};

}
#endif
